package com.dx.pf.dal.jdbc.mapper;

import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.Assert;

import com.dx.pf.dal.cache.DalCache;
import com.dx.pf.dal.cache.EntryInfo;

/**
* @ClassName: PojoRowMapperResultSetExtractor 
* @Description: 
* @author wuzhenfang(zhenfangwu@capitalbio.com) 
* @date 2015年5月31日 上午9:47:51 
* @version V1.0
 */
public class PojoRowMapperResultSetExtractor<T> implements RowMapper<T>{

	/** 映射类 */
	private Class<T> mappedClass;
	
	/** 检查完全填充 是否通过严格验证 */
	private boolean checkFullyPopulated = false;

	/** 我们是否违约原语时映射null值 */
	private boolean primitivesDefaultedForNullValue = false;
	
	/**列参数对应的参数属性*/
	private Map<String, PropertyDescriptor> mappedFields;
	
	private EntryInfo entryInfo = null;
	
	public PojoRowMapperResultSetExtractor(Class<T> mappedClass){
		initialize(mappedClass);
	}
	
	protected void initialize(Class<T> mappedClass) {
		this.mappedClass = mappedClass;
		this.mappedFields = new HashMap<String, PropertyDescriptor>();
		this.entryInfo = DalCache.getInstance().getEntryPropertyMap(mappedClass);
		this.mappedFields = entryInfo.getFieldNamePropertyDesc();
	}

	/**
	 * @Description: 设置要映射的对象类 
	 * @param mappedClass void
	 * @throws
	 */
	public void setMappedClass(Class<T> mappedClass) {
		if (this.mappedClass == null) {//如果该
			initialize(mappedClass);
		}else if(!this.mappedClass.equals(mappedClass)){
			//TODO 
		}
	}
	
	/**
	 * 
	 */
	public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
		Assert.state(this.mappedClass != null, "Mapped class was not specified");
		T mappedObject = BeanUtils.instantiate(this.mappedClass);
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);
		
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();
		for (int index =1; index <= columnCount ;index++) {
			String column = JdbcUtils.lookupColumnName(rsmd, index);//获得当前列名称
			PropertyDescriptor pd = mappedFields.get(column.replaceAll(" ", ""));
			if(pd != null){
				Object value = getColumnValue(rs, index, pd);
				if(value != null){
					bw.setPropertyValue(pd.getName(), value);//设置值
				}
			}
		}
		return mappedObject;
	}
	
	/**
	 * @Description: 通过JDBCUtil返回值
	 * @param rs
	 * @param index
	 * @param pd
	 * @return
	 * @throws SQLException Object
	 * @throws
	 */
	protected Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd) throws SQLException {
		return JdbcUtils.getResultSetValue(rs, index, pd.getPropertyType());
	}

	/**
	 * @Description: 初始化
	 * @param mappedClass
	 * @return PojoRowMapperResultSetExtractor<T>
	 * @throws
	 */
	public static <T> PojoRowMapperResultSetExtractor<T> newInstance(Class<T> mappedClass) {
		PojoRowMapperResultSetExtractor<T> newInstance = new PojoRowMapperResultSetExtractor<T>(mappedClass);
		return newInstance;
	}
}
